<?php
namespace app\common\library\mstching;
use app\common\model\WebSet;
use app\common\model\PrinterLog;

/*
 * 易联云打印机驱动模块
 * 测试机型号：K4-WH
*/
class YiLian
{
	private $baseurl = '';//接口路径
	private $appid = '';		
	private $appsecret = '';
	private $access_token = '';
	
	/**
	 * 构造函数
	 */
	public function __construct()
	{
		$values = WebSet::getItem('printer');
		$this->baseurl = $values['yilian']['api_url'];
		$this->appid = $values['yilian']['app_key'];
		$this->appsecret = $values['yilian']['app_secret'];
		$this->access_token = $values['yilian']['access_token'];
		
	}
	
	/**
	* 打印订单接口
	* $machine_code 打印机终端号
	* $n 打印份数
	*/
	public function printMsg($data ,$machine_code,$n=1,$tpl)
	{
		if($tpl==0){
			$content = $this->make_order_templet($data,$n);//制作订单模板
		}else{
			$content = $this->make_refund_templet($data,$n);//制作退单模板
		}
		$params = $this->params();
		$params['machine_code'] = $machine_code;//打印机终端号
		$params['origin_id'] = $data['order_id'];//订单编号
		$params['content'] = $content;//打印内容
        $res = json_decode($this->http_post_json($params,'print/index'),true);
		if($res['error']!=0){
			//记录打印失败日志
			$model = new PrinterLog;
			$model->save([
				'brand' => 30,
				'open_user_id' => $machine_code,
				'uuid' => '',
				'tpl' => $tpl,
				'content' => $content,
				'order_no' => $data['order_no'],
				'shop_id' => $data['shop_id'],
				'wxapp_id' => $data['wxapp_id']
			]);
		}
		return true;
	}
	
	/**
	* 授权绑定打印机
	*/
	public function printerAdd($data)
	{
		$params = $this->params();
		$params['print_name'] = $data['printer_name'];//自定义打印机名称(可填)
		$params['machine_code'] = $data['uuid'];//打印机终端号
		$params['msign'] = $data['key'];//打印机终端密钥
		$params['phone'] = $data['phone'];//手机卡号码(可填)
        $res = json_decode($this->http_post_json($params,'printer/addprinter'),true);
		if($res['error']==0){
			return false;
		}
		return $this->err_msg($res['error']);
	}
	
	/**
	* 删除授权绑定的打印机
	*/
	public function printerDel($machine_code){
		$params = $this->params();
		$params['machine_code'] = $machine_code;//打印机编号
		$res = json_decode($this->http_post_json($params,'printer/deleteprinter'),true);
		if($res['error']==0){
			return false;
		}
		return $this->err_msg($res['error']);
	}
	
	/**
	* 获取打印机状态接口 
	*/
	public function queryPrinterStatus($machine_code){
		$params = $this->params();
		$params['machine_code'] = $machine_code;//打印机编号
		$res = json_decode($this->http_post_json($params,'printer/getprintstatus'),true);
		if($res['error']==0){
			$msg = '离线';
			if($res['body']['state']==1){
				$msg = '正常';
			}
			if($res['body']['state']==2){
				$msg = '缺纸';
			}
			return $msg;
		}
		return false;
	}

	/**
	* 获取Token
	*/
	public function getToken($appid,$appsecret)
    {
		$this->appid = $appid;
		$this->appsecret = $appsecret;
        $time = time();
        $params = [
            'client_id' => $this->appid,
            'timestamp' => $time,
            'sign' => $this->getSign($time),
            'id' => $this->uuid4(),
            'scope' => 'all'
        ];
        $params['grant_type'] = 'client_credentials';
        $res = json_decode($this->http_post_json($params,'oauth/oauth'),true);
		if($res['error']==0){
			return $res['body']['access_token'];
		}
		return '';
    }
	
	/**
	* 公共参数
	*/
	private function params(){
		$time = time();         //请求时间
		return $params = [
			'client_id' => $this->appid,
			'access_token' => $this->access_token,
            'timestamp' => $time,
            'sign' => $this->getSign($time),
            'id' => $this->uuid4(),
		];
	}
	
	/**
	* 生成签名
	*/
	private function getSign($timestamp)
    {
        return md5($this->appid . $timestamp . $this->appsecret);
    }

	/**
	* 生成uuid4
	*/
    private function uuid4(){
        mt_srand((double)microtime() * 10000);
        $charid = strtolower(md5(uniqid(rand(), true)));
        $hyphen = '-';
        $uuidV4 =
            substr($charid, 0, 8) . $hyphen .
            substr($charid, 8, 4) . $hyphen .
            substr($charid, 12, 4) . $hyphen .
            substr($charid, 16, 4) . $hyphen .
            substr($charid, 20, 12);
        return $uuidV4;
    }
	
	
	//发送post请求
	/**
	 * PHP发送Json对象数据
	 * @return string
	 */
	private function http_post_json($data,$url)
	{
		$url = $this->baseurl . $url;
		$data = http_build_query($data);
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Expect:'
        )); // 解决数据包大不能提交
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循
        curl_setopt($ch, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
		$response = curl_exec($ch);
		$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
		curl_close($ch);
		return $response;
	}

	/**
	 * 制作订单模板
	 * $data 订单数据
	 * $n 打印份数
	 * 58mm的机器,一行打印16个汉字,32个字母;
	 */
	private function make_order_templet($data,$n)
	{
		if($data['order_mode']['value']==10){
			if(isset($data['table']['table_name'])){
				$title = $data['table']['table_name'];
			}else{
				$title = '堂食'.$data['row_no'].'号';
			}
		}
		if($data['order_mode']['value']==20){
			$title = '外卖'.$data['row_no'].'号';
		}
		if($data['order_mode']['value']==30){
			$title = '自取'.$data['row_no'].'号';
		}
		$content = '<MN>'.$n.'</MN>';
		$content .= '<FS><center># '.$title.' #</center></FS>';
		if($data['arrive_time']['value']>0){
			$content .= '到店时间:'.$data['arrive_time']['text']."\n";
		}
		$content .= str_repeat('-', 32);
		$content .= '<center>'.$data['shop']['shop_name'].'</center>';
		if($data['transaction_id']){
			$content .= '<center>-- 微信支付 --</center>';
		}else{
			$content .= '<center>-- 余额支付 --</center>';
		}
		
		$content .= '支付时间:'.date("Y-m-d H:i:s",$data['pay_time'])."\n";
		$content .= "<FS>名称        数量</FS>\n";//16=4+8+4
		$content .= str_repeat('-', 32);
		//循环拼接打印模板
		for ($i = 0; $i < sizeof($data['goods']); $i++) {
				$goods_name = $data['goods'][$i]['goods_name'].$data['goods'][$i]['goods_attr'];//产品名字
				$total_num = $data['goods'][$i]['total_num'];	//产品数量
				//设置名称字符长度
				$lan = mb_strlen($goods_name,'utf-8')*2;//一个汉字2个字符长度
				for($n=$lan;$n<13;$n++){
					$goods_name .= ' ';
				}
				$content .= '<FS>' . $goods_name . '×' . $total_num."</FS>\n";
		}
		$content .= str_repeat('-', 32);
		$content .= '商品金额：+￥'.$data['total_price']."\n";
		if($data['express_price']>0){
			$content .= '配送费用：+￥'.$data['express_price']."\n";
		}
		if($data['pack_price']>0){
			$content .= '餐盒费用：+￥'.$data['pack_price']."\n";
		}
		if($data['ware_price']>0){
			$content .= '餐具调料：+￥'.$data['ware_price']."\n";
		}
		if($data['activity_price']>0){
			$content .= '优惠金额：-￥'.$data['activity_price']."\n";
		}
		$content .= '实付金额：￥'.$data['pay_price']."\n";
		if($data['flavor']){
			$content .= '口味要求：'.$data['flavor']."\n";
		}
		if($data['message']){
			$content .= '顾客留言：'.$data['message']."\n";
		}
		if($data['order_mode']['value']==20){
			$content .= '配送地址：'.$data['address']['detail']."\n";
			$content .= '接 收 人：'.$data['address']['name'].$data['address']['phone']."\n";
		}
		$content .= '<FS><center># '.$title.' # 完</center></FS>';
		$content .= "\n";
		return $content;
	}
	
	/**
	 * 制作退单模板
	 * $data 退单数据
	 * $n 打印份数
	 * 58mm的机器,一行打印16个汉字,32个字母;
	 */
	private function make_refund_templet($data,$n)
	{
		if($data['order_mode']['value']==10){
			if(isset($data['table']['table_name'])){
				$title = $data['table']['table_name'];
			}else{
				$title = '堂食'.$data['row_no'].'号';
			}
		}
		if($data['order_mode']['value']==20){
			$title = '外卖'.$data['row_no'].'号';
		}
		if($data['order_mode']['value']==30){
			$title = '自取'.$data['row_no'].'号';
		}
		$content = '<MN>'.$n.'</MN>';
		$content .= '<FS><center># 退单 #</center></FS>';
		$content .= '<FS><center>- '.$title.' -</center></FS>';
		$content .= str_repeat('-', 32);
		$content .= '<center>'.$data['shop']['shop_name'].'</center>';
		$content .= "<FS>名称        数量</FS>\n";//16=4+8+4
		$content .= str_repeat('-', 32);
		//循环拼接打印模板
		for($i = 0; $i < sizeof($data['goods']); $i++) {
			if($data['goods'][$i]['refund_num']>0){
				$goods_name = $data['goods'][$i]['goods_name'].$data['goods'][$i]['goods_attr'];//产品名字
				$refund_num = $data['goods'][$i]['refund_num'];	//产品数量
				//设置名称字符长度
				$lan = mb_strlen($goods_name,'utf-8')*2;//一个汉字2个字符长度
				for($n=$lan;$n<13;$n++){
					$goods_name .= ' ';
				}
				$content .= '<FS>' . $goods_name . '×' . $refund_num."</FS>\n";
			}
		}
		$content .= str_repeat('-', 32);
		$content .= '支付金额：￥'.$data['pay_price']."\n";
		$content .= '退款金额：￥'.$data['refund_price']."\n";
		$content .= '退款理由：'.$data['refund_desc']."\n";
		$content .= "<FS><center># 退款 # 完</center></FS>\n\n";
		return $content;
	}
	
	/**
	 * 错误消息
	 */
	private function err_msg($err)
	{
		$msg = [
			0 => 'success',
			1 => 'response_type非法',
			2 => 'client_id不存在',
			3 => 'redirect_uri不匹配',
			4 => 'client_id、response_type、state均不允许为空',
			5 => 'client_id或client_secret错误',
			6 => 'code错误或已过期',
			7 => '账号密码错误',
			8 => '打印机信息错误,参数有误',
			9 => '连接打印机失败,参数有误',
			10 => '权限不足',
			11 => 'sign验证失败',
			12 => '缺少必要参数',
			13 => '打印失败,参数有误',
			14 => 'access_token错误',
			15 => '权限不能大于初次授权的权限',
			16 => '不支持k1,k2,k3机型',
			17 => '该打印机已被他人绑定',
			18 => 'access_token过期或错误,请刷新access_token或者重新授权',
			19 => '应用未上架或已下架',
			20 => 'refresh_token已过期,请重新授权',
			21 => '关闭或重启失败',
			22 => '声音设置失败',
			23 => '获取机型和打印宽度失败',
			24 => '操作失败，没有订单可以被取消',
			25 => '未找到机型的硬件和软件版本',
			26 => '取消logo失败',
			27 => '请设置scope,权限默认为all',
			28 => '设置logo失败',
			29 => 'client_id,machine_code,qr_key不能为空',
			30 => 'machine_code,qr_key错误',
			31 => '接口不支持自有应用服务模式',
			32 => '订单确认设置失败',
			33 => 'Uuid不合法',
			34 => '非法操作',
			35 => 'machine_code或msign错误',
			36 => '按键打印开启或关闭失败',
			37 => '添加应用菜单失败',
			38 => '应用菜单内容错误,content必须是Json数组',
			39 => '应用菜单个数超过最大个数',
			40 => '应用菜单内容错误,content中的name值重名',
			41 => '获取或更新access_token的次数,已超过最大限制次数!',
			42 => '该机型不支持面单打印',
			43 => 'shipper_type错误',
			44 => '未知错误',
			45 => '系统错误!请立即反馈',
			46 => 'picture_url错误或格式错误',
			47 => '参数错误,"body":"xxxxx"',
			48 => '无法设置,该型号版本不支持!',
			49 => '错误,"body":"xxxxx"'
		];
		if(isset($msg[$err])){
			return $msg[$err];
		}
		return '未知错误';
	}
}